package thoughtworks.test;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TextInputConversion {

	private List <String> dataStrings;
	private List<String> questions;
	private RomanToNumberConversion romanConversionObj;
	private Map<String,ValueVo> dataMap;
	Pattern numberPattern = Pattern.compile("\\d+" );

	public TextInputConversion(RomanToNumberConversion romanConversionObj){
		this.romanConversionObj = romanConversionObj;
	}
	//This method is used to separate the input text to data and questions.
	//Questions are identified with "?" and others are data
	public void convert(BufferedReader reader) throws InvalidRomanException {
		dataStrings = new LinkedList<String>();
		questions = new ArrayList<String>();
		String line;
		try {
			while ((line = reader.readLine()) != null) {
				if (line.indexOf("?") == -1) {
					dataStrings.add(line.trim());
				} else {
					questions.add(line.trim());
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		processData();
		processQuestions();
	}
	//This method is used to process the data given in input text
	//I am out of imagination for naming variables :)
	public void processData() throws InvalidRomanException{
		dataMap = new HashMap<String, ValueVo>();
		List<String> tempDataStrings = new ArrayList<String>();
		for(String text : dataStrings){
			List<String> tempDataList = Arrays.asList(text.split(" "));
			if(ConstantsUtil.romanValues.keySet().contains(tempDataList.get(tempDataList.size()-1).trim())){
				String romanValue = tempDataList.get(tempDataList.size()-1).trim();
				dataMap.put(tempDataList.get(0), new ValueVo(romanValue, ConstantsUtil.romanValues.get(romanValue)));
			} else {
				tempDataStrings.add(text.trim());
			}
		}
		for (String text : tempDataStrings) {
			List<String> parseList = Arrays.asList(text.substring(0,
					text.indexOf("is ")).split(" "));
			Matcher m = numberPattern.matcher(text);
			int value = 0;
			int romanValue = 0;
			while (m.find()) {
				value = Integer.valueOf(m.group());
			}
			StringBuilder string = new StringBuilder();
			for(int i=0; i < parseList.size()-1; i++){
				string.append(dataMap.get(parseList.get(i)).getRomanValue().trim());
			}
			try {
				romanValue = romanConversionObj.convertRomanNumeral(string.toString().trim());
			} catch (InvalidRomanException exception) {
				throw new InvalidRomanException(exception.getMessage());
			}
			dataMap.put(parseList.get(parseList.size()-1), new ValueVo(null, (value/romanValue)));
		}
	}
	//This method is used to reply for the questions asked in the input text using the data provided in text. 
	public void processQuestions() throws InvalidRomanException{
		for(String text : questions){
			List<String> parseList =  Arrays.asList(text.substring(text.indexOf("is ")+3, text.indexOf(" ?")).split(" "));
			StringBuilder string = new StringBuilder();
			String reply = null;
			for(int i = 0; i < parseList.size(); i++){
				String parsedText = parseList.get(i).trim();
				if(dataMap.keySet().contains(parsedText)){
					String romanValue = dataMap.get(parsedText).getRomanValue();
					if(romanValue != null){
						string.append(romanValue.trim());
						reply = (i==parseList.size()-1) ? getAnswer(parseList, String.valueOf(getValue( string.toString()))) : null;
					} else {
						reply = (i==parseList.size()-1) ? getAnswer(parseList, String.valueOf(getValue(string.toString(), parsedText))) : "i have no idea what you are talking";
					}
				} else {
					reply = "i have no idea what you are talking";
					break;
				}
			}
			System.out.println(reply);
		}
	}
	
	private String getAnswer(List<String> list, String value){
		StringBuilder reply = new StringBuilder();
		for(String text : list){
			reply.append(text + " ");
		}
		return reply.toString() + "is " + value +" credits";
	}
	
	private int getValue(String romanLetter,String text) throws InvalidRomanException{
		return dataMap.get(text.trim()).getValue() * getValue(romanLetter);
	}
	
	private int getValue(String text) throws InvalidRomanException{
		return romanConversionObj.convertRomanNumeral(text);
	}
	
	
}
